package steveshrader.budget.client.widgets;

import java.util.Date;
import java.util.List;

import steveshrader.budget.client.FieldsHelper;
import steveshrader.budget.client.events.ExpensesChangeEvent;
import steveshrader.budget.client.events.ModifiedExpenseEvent;
import steveshrader.budget.shared.BudgetRequestFactory;
import steveshrader.budget.shared.ExpenseProxy;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.web.bindery.requestfactory.shared.Receiver;

/**
 * A UI Widget that allows a user to filter the expenses being displayed in the
 * dynamic table.
 */
public class ExpenseFilterWidget extends Composite {

  interface Binder extends UiBinder<Widget, ExpenseFilterWidget> {
  };

  @UiField
  DateBox startDate;
  @UiField
  DateBox endDate;
  @UiField(provided = true)
  SuggestBox vendor;
  @UiField
  Button refresh;
  @UiField
  Button clear;

  private final EventBus eventBus;
  private final BudgetRequestFactory requestFactory;
  private boolean getExpensesPending;
  
  @UiConstructor
  public ExpenseFilterWidget(EventBus eventBus, BudgetRequestFactory requestFactory, FieldsHelper fieldsHelper) {
    this.eventBus = eventBus;
    this.requestFactory = requestFactory;
    
    //setup suggest box for vendor
    vendor = new SuggestBox(fieldsHelper.getVendorOracle());
    
    initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));
    
    //setup default date info...
    startDate.setFormat(FieldsHelper.DATE_BOX_FORMAT);
    endDate.setFormat(FieldsHelper.DATE_BOX_FORMAT);    
    
    defaultFieldValues();
    
    ModifiedExpenseEvent.register(eventBus, new ModifiedExpenseEvent.Handler() {
        public void onExpenseSaved(ModifiedExpenseEvent e) {
      	  getExpenses();
        }
      });
    
    getExpenses();
  }

  @UiHandler("refresh")
  public void handleRefreshClick(ClickEvent e) {
    getExpenses();
  }

  @UiHandler("clear")
  public void handleClearClick(ClickEvent e) {
	  defaultFieldValues();
	  getExpenses();
  }

  private void defaultFieldValues() {
	  Date date = new Date();
	  CalendarUtil.setToFirstDayOfMonth(date);        //find the 1st day of the current month
	  startDate.setValue(date);    					//default to 1st day of the current month
	  CalendarUtil.addMonthsToDate(date, 1);          //find the 1st day of the next month
	  CalendarUtil.addDaysToDate(date, -1);           //go back one day to the last day of the current month
	  endDate.setValue(date);              			//default to the last day of the current month
	  vendor.setValue(null);  
  }
  
  private void getExpenses() {
	  if(getExpensesPending) {
		  //a request has already been sent...don't keep firing requests but wait for the results
	  }
	  else {
		getExpensesPending = true;
		Scheduler.get().scheduleFinally(new ScheduledCommand() {
			public void execute() {
			    requestFactory.budgetServiceRequest().getExpenses(startDate.getValue(), endDate.getValue(), vendor.getText()).fire(
			        new Receiver<List<ExpenseProxy>>() {
			          @Override
			          public void onSuccess(List<ExpenseProxy> response) {
			            eventBus.fireEvent(new ExpensesChangeEvent(response));
			          }
			        });
			    getExpensesPending = false;  
			}
		});
	  }
  }
}
